package Net;

import java.io.IOException;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;

import Interfaces.EventLoopReadCallback;
import Interfaces.UdpServerOnReadCallback;
import Util.ApiException;

public class UdpServer implements EventLoopReadCallback
{
	private final int BUFFER_SIZE = 1024*64;
	private ByteBuffer byteBuffer_;
	private int port_;
	private EventLoop loop_;
	private DatagramChannel channel_;
	private DatagramSocket socket_;
	private UdpServerOnReadCallback readCb_;
	
	
	public void setReadCallback(UdpServerOnReadCallback cb)
	{
		readCb_ = cb;
	}
	
	public UdpServer(EventLoop loop,int port)
	{
		loop_ = loop;
		port_ = port;
		byteBuffer_ = ByteBuffer.allocate(BUFFER_SIZE);
	}
	
	public void listen() throws IOException
	{
		channel_ = DatagramChannel.open();
		socket_ = channel_.socket();
		socket_.bind(new InetSocketAddress(port_));
		channel_.configureBlocking(false);
		channel_.register(loop_.getSelector(), SelectionKey.OP_READ);
		loop_.setReadCb(this);
	}

	@Override
	public void onRead(SelectionKey key) throws IOException, ApiException {
		// TODO Auto-generated method stub
		DatagramChannel datagramChannel = ( DatagramChannel ) key .channel () ;
		byteBuffer_.clear();
		InetSocketAddress sa = (InetSocketAddress)datagramChannel.receive ( byteBuffer_ ) ; 
		if (readCb_!=null)
			readCb_.onReadCallback(sa, byteBuffer_, byteBuffer_.position());
	}
	
	public int onSendMessage(InetSocketAddress sa, ByteBuffer buffer) throws IOException
	{
		return channel_.send(buffer, sa);
	}
}
